import { ElMessage } from 'element-plus'
import { storeToRefs } from 'pinia'
import {
  COMPANY_PRODUCT_LIST,
  CONDITION_TABLE_OF_MAJOR_ENERGY_CONSUMING_EQUIPMENT,
  DETAILED_LIST_OF_COMPANY_INDICATORS,
  ENERGY_CONSUMPTION_STRUCTURE_SUB_TABLE,
  ENERGY_CONSUMPTION_STRUCTURE_TABLE,
  ENERGY_SAVING_RENOVATION_PROJECT_INFORMATION_TABLE,
  ENTERPRISE_BASIC_INFORMATION_TABLE_ID,
  PROGRESS_ENERGY_SAVING_TARGET_COMPLETION_TABLE,
  TABLE_FIELD_QUARTER,
  TABLE_FIELD_YEAR,
  TABLE_OF_COMPREHENSIVE_ENERGY_CONSUMPTION_PER_UNIT_PRODUCT,
} from './config'
import {
  type EnergyDataReportInformant,
  type IntervalHandle,
  StatementStatus,
} from './types'
import type { ReportList } from './useLoadList'
import { useStatementStore } from '@/store'
import {
  saveOrUpdateCompanyIndicatorDetails,
  saveOrUpdateCompanyProduct,
  saveOrUpdateEnergyConsumptionStructure,
  saveOrUpdateEnergyConsumptionStructureSchedule,
  saveOrUpdateEquipmentStatus,
  saveOrUpdateGoalCompletionStatus,
  saveOrUpdateProductEnergyConsumption,
  saveOrUpdateReconstructionProject,
  saveOrUpdateUnitDetails,
} from '@/api/modules/enterpriseQuarterlyReport'

export type StatementStore = ReturnType<
  typeof useStatementStore
>

export default function useReportSave(
  lists: Ref<ReportList[]>,
  informant: Ref<EnergyDataReportInformant>,
  option?: {
    getCalc?: (
      row: number,
      prop: string,
      value?: string | number | undefined
    ) => number | string | undefined
    getReportData?: (store: StatementStore) => any
    assignExtraData?: (params: any, option: {
      data: any[]
      state: StatementStatus
      illustrate: string
    }) => void
  },
) {
  const statementStore = useStatementStore()
  const {
    statementId,
    year,
    quarter,
    enterpriseId,
    statementFlattenColumns: flattenColumns,
  } = storeToRefs(statementStore)

  const save = computed(() => {
    const tableAccountId = Number(statementId.value)
    let method = null
    switch (tableAccountId) {
      case PROGRESS_ENERGY_SAVING_TARGET_COMPLETION_TABLE.ID:
        method = saveOrUpdateGoalCompletionStatus
        break
      case TABLE_OF_COMPREHENSIVE_ENERGY_CONSUMPTION_PER_UNIT_PRODUCT.ID:
        method = saveOrUpdateProductEnergyConsumption
        break
      case CONDITION_TABLE_OF_MAJOR_ENERGY_CONSUMING_EQUIPMENT.ID:
        method = saveOrUpdateEquipmentStatus
        break
      case ENERGY_SAVING_RENOVATION_PROJECT_INFORMATION_TABLE.ID:
        method = saveOrUpdateReconstructionProject
        break
      case ENERGY_CONSUMPTION_STRUCTURE_TABLE.ID:
        method = saveOrUpdateEnergyConsumptionStructure
        break
      case COMPANY_PRODUCT_LIST.ID:
        method = saveOrUpdateCompanyProduct
        break
      case DETAILED_LIST_OF_COMPANY_INDICATORS.ID:
        method = saveOrUpdateCompanyIndicatorDetails
        break
      case ENERGY_CONSUMPTION_STRUCTURE_SUB_TABLE.ID:
        method
          = saveOrUpdateEnergyConsumptionStructureSchedule
        break
      case ENTERPRISE_BASIC_INFORMATION_TABLE_ID:
        method = saveOrUpdateUnitDetails
        break
    }
    return method
  })

  const defaultGetData = () => {
    const props = flattenColumns.value.map(v => v.prop)
    const isNotEmpty = (
      array: ReportList['data'],
    ): boolean =>
      array.some((v) => {
        return v.value !== '' && v.value != null
      })

    const listsData = lists.value.map(v => v.data)
    const listsValue = listsData.filter(v => isNotEmpty(v))
    return listsValue.map((v, i) => {
      const obj = {} as any
      props?.forEach((prop, index) => {
        obj[prop] = option?.getCalc
          ? option.getCalc(
            i,
            prop,
            (v[index] as any).value,
          ) || ''
          : v[index]?.value || ''
      })
      obj[TABLE_FIELD_YEAR] = String(year.value)
      obj[TABLE_FIELD_QUARTER] = String(quarter.value)
      return obj
    })
  }

  const getData = () => {
    if (option?.getReportData) {
      return option.getReportData(statementStore)
    }
    return defaultGetData()
  }

  const saveOrUpdate = async (
    state: StatementStatus,
    illustrate = '',
    callback?: (res: any) => any,
  ) => {
    const data = getData()
    const informer = toValue(informant)
    const params: any = {
      [TABLE_FIELD_YEAR]: String(year.value),
      [TABLE_FIELD_QUARTER]: String(quarter.value),
      tenantId: enterpriseId.value,
      ...informer,
    }

    // TODO
    params.list = (data || []).map((v: any) => ({
      ...v,
      state,
      illustrate,
    }))

    // 追加额外的数据，比如合计等
    option?.assignExtraData?.(params, {
      data,
      state,
      illustrate,
    })

    if (save.value) {
      // console.log('params: ', params);
      return save.value(params).then((res: any) => {
        callback?.(res)
      })
    }
    else {
      return Promise.resolve()
    }
  }

  async function report() {
    await saveOrUpdate(StatementStatus.REPORTED)
    ElMessage.success('操作成功')
  }
  async function saveStage() {
    await saveOrUpdate(StatementStatus.STAGED)
    ElMessage.success('操作成功')
  }

  // 是否开启自动暂存
  const needAutoSave = false
  let timer: IntervalHandle
  const autoSave = () => {
    saveOrUpdate(StatementStatus.STAGED)
  }

  if (needAutoSave) {
    onBeforeUnmount(() => {
      timer && clearInterval(timer)
    })
    onDeactivated(() => {
      timer && clearInterval(timer)
    })

    onActivated(() => {
      timer = setInterval(() => {
        autoSave()
      }, 10e3)
    })
    onMounted(() => {
      timer = setInterval(() => {
        autoSave()
      }, 10e3)
    })
  }

  return {
    report,
    saveStage,
  }
}
